<!--
 * @Author: zhao 13370229059@163.com
 * @Date: 2024-05-08 22:27:25
 * @LastEditors: zhao 13370229059@163.com
 * @LastEditTime: 2024-12-18 22:54:32
 * @FilePath: \dance\pages\me\pushVideo.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
  <cover v-if="coverDom.width" ref="coverRef" v-model="form.cover" :coverDom="coverDom" :dragPosition="dragPosition" />
  <view class="video">
    <uv-status-bar bgColor="#ff7a66"></uv-status-bar>
    <!--自定义头部 -->
    <view class="push-navbar">
      <zy-navbar></zy-navbar>
    </view>
    <view class="video-title"></view>
    <uv-form :model="form" :rules="rules" ref="formRef" :borderBottom="false" :labelStyle="{ color: '#fff' }" labelWidth="163rpx" class="video-fill">
      <uv-form-item label="" prop="address">
        <view class="video-mp4">
          <view> MP4 </view>
          <view class="video-mp4-file" @click="onModalVideo">
            <view class="video-mp4-file-button" @click.stop="onChangeVideo">上传视频</view>
            <video
              :src="form.address"
              class="video-mp4-file-video"
              :show-play-btn="false"
              :show-center-play-btn="false"
              :show-fullscreen-btn="false"
              :controls="false"
              object-fit="fill"
              v-if="form.address"
            ></video>
          </view>
          <view class="video-mp4-cover">
            <view class="video-mp4-cover-content" @click="onModalCover">
              <view class="video-mp4-file-button video-mp4-cover-content-button" @click.stop="onChooseImage">上传封面</view>
              <uv-image :src="form.cover" mode="widthFix" class="video-mp4-cover-image" width="100%" height="100%" v-if="form.cover"></uv-image>
              <view
                class="video-mp4-cover-share"
                :style="{ height: coverDom.width * (4 / 5) + 'px', top: dragPosition + 'px' }"
                @touchstart="startDrag"
                @touchmove="doDrag"
                @touchend="endDrag"
              ></view>
            </view>
            <view class="video-mp4-cover-info">建议上传封面，曝光更高。虚线框内转发封面</view>
          </view>
        </view>
      </uv-form-item>
      <uv-form-item label="标题" prop="title" required>
        <input v-model="form.title" border="none" placeholder="请输入标题" class="input" />
      </uv-form-item>
      <uv-form-item label="作品描述" prop="content">
        <textarea v-model="form.description.content" placeholder="请输入作品描述" auto-height class="textarea"> </textarea>
      </uv-form-item>
    </uv-form>
    <uv-divider text=""></uv-divider>
    <uv-button type="error" text="确定" @click="onSubmit" shape="circle" :customStyle="{ backgroundColor: '#FF7A66' }"></uv-button>
    <uv-safe-bottom></uv-safe-bottom>
  </view>
  <uv-toast ref="toastRef"></uv-toast>
  <uv-preview-video ref="previewVideo"></uv-preview-video>
</template>

<script setup>
  import cover from './components/cover.vue';
  import { reactive, ref, nextTick, getCurrentInstance } from 'vue';
  import { onLoad, onShow, onReady, onHide } from '@dcloudio/uni-app';
  import { onHome, onLeft, uploadFn } from '@/common/js/fn';
  import throttle from '@/uni_modules/uv-ui-tools/libs/function/throttle.js';
  let coverDom = ref({});
  let startY = ref(),
    dragPosition = ref(0);
  let toastRef = ref();
  let form = reactive({
    title: '',
    description: {
      content: ''
    },
    cover: '',
    address: '',
    id: 0,
    forwardCover: '',
    standby: ''
  });
  let toastFn = (text, type = 'error') => {
    toastRef.value.show({
      overlay: false,
      message: text,
      type: type
    });
  };
  let formRef = ref(),
    rules = reactive({
      address: [
        { required: true, message: '视频不能为空', trigger: ['blur', 'change'] },
        {
          // 自定义验证函数，见上说明，注意这里面的逻辑不能出现语法报错，否则可能导致不验证
          validator: (rule, value, callback) => {
            return !!form.cover;
          },
          message: '封面不能为空',
          trigger: ['blur']
        }
      ],
      title: [{ required: true, message: '此为必填字段', trigger: ['blur', 'change'] }]
    });
  let coverRef = ref();
  // 点击保存
  const httpSave = async () => {
    let params = JSON.parse(JSON.stringify(form));
    // 转发封面
    if (params.cover && params.standby !== dragPosition.value) {
      params.forwardCover = await coverRef.value.extendCanvas();
    }
    params.standby = dragPosition.value + '';
    await uni.$uv.http.post(`app/${params.id ? 'video/update' : 'teacher/publish'}`, params);
    toastFn('保存成功!', 'success');
    onLeft();
  };

  // #region 视频详情
  let routerVal = ref();
  const httpVideoDetail = async () => {
    let res = await uni.$uv.http.post(`/app/video/detail`, { id: routerVal.value });
    form.title = res.title;
    form.cover = res.cover;
    form.description.content = res.description?.content;
    form.id = routerVal.value;
    form.address = res.address;
    if (res.standby) {
      dragPosition.value = form.standby = Number(res.standby);
    }
    form.forwardCover = res.forwardCover;
  };
  const { ctx } = getCurrentInstance();
  onLoad(async val => {
    let { width, height } = await ctx.$uv.getRect('.video-mp4-cover-content');
    coverDom.value = { width: parseInt(width), height };
    dragPosition.value = parseInt(height / 2) - (coverDom.value.width * (4 / 5)) / 2;
    if (!val.id) return;
    routerVal.value = Number(val.id);
    httpVideoDetail();
  });
  // #endregion
  const httpUpload = async event => {
    try {
      const result = await uploadFn(event.tempFilePath);
      form.address = result;
    } catch (error) {
      toastFn('上传失败');
    }
  };
  onReady(async () => {
    formRef.value.setRules(rules);
  });
  // 预览视频
  let previewVideo = ref();
  const onModalVideo = () => {
    previewVideo.value.open(form.address);
  };
  // 视频操作
  const onChangeVideo = () => {
    uni.chooseVideo({
      sourceType: ['album'],
      success: res => {
        httpUpload(res);
      }
    });
  };
  // 预览封面
  const onModalCover = () => {
    uni.previewImage({
      urls: [form.cover]
    });
  };
  const onChooseImage = () => {
    uni.chooseImage({
      count: 1,
      sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图，默认二者都有
      sourceType: ['album', 'camera'], //从相册选择
      success: async event => {
        try {
          const result = await uploadFn(event.tempFilePaths[0]);
          form.cover = result;
        } catch (error) {
          toastFn('上传失败');
        }
      }
    });
  };
  // #region 拖拽选择转发封面
  // 开始拖拽
  const startDrag = e => {
    e.preventDefault();
    startY.value = e.touches[0].clientY;
  };
  // 拖拽中
  const doDrag = e => {
    throttle(() => {
      e.preventDefault();
      const currentY = e.touches[0].clientY;
      const deltaY = currentY - startY.value;
      dragPosition.value = dragPosition.value + deltaY;
      startY.value = currentY;
      if (dragPosition.value <= 0) dragPosition.value = 0;
      let height = coverDom.value.height - coverDom.value.width * (4 / 5);
      if (dragPosition.value >= height) dragPosition.value = height;
    }, 100);
  };
  // 结束拖拽
  const endDrag = () => {
    // 可以在这里添加拖动后的处理逻辑
  };
  // #endregion
  const onSubmit = () => {
    formRef.value
      .validate()
      .then(() => {
        httpSave();
      })
      .catch(error => {
        toastFn('请检查必填项');
      });
  };
</script>

<style lang="scss" scoped>
  .video {
    background-color: #1d1f24;
    width: 100vw;
    height: calc(100vh - env(safe-area-inset-bottom));
    padding: 0 26rpx;
    display: flex;
    box-sizing: border-box;
    flex-direction: column;
    color: #fff;
    overflow-y: auto;
    &-title {
      padding-top: $dance-navbar-top-height;
    }
    &-introduce {
      display: flex;
      flex-direction: column;
      background-color: #959595;
      border-radius: 19rpx;
      padding: 17rpx 21rpx;
      &-item {
        display: flex;
        align-items: center;
        color: #fff;
        #item-textarea {
          height: 314rpx;
          padding-left: 0 !important;
          padding-right: 0 !important;
        }
      }
    }
    &-mp4 {
      display: flex;
      flex-direction: column;
      width: 100%;
      color: #fff;
      font-size: 28rpx;
      position: relative;
      margin-bottom: 453rpx;
      text-align: center;
      &-file {
        width: 344rpx;
        height: 485rpx;
        background-color: #959595;
        border-radius: 19rpx;
        position: relative;
        overflow: hidden;
        margin-top: 35rpx;
        &-button {
          position: absolute;
          top: 21rpx;
          left: 50%;
          transform: translateX(-50%);
          padding: 17rpx 21rpx;
          border: 1px solid #fff;
          background-color: rgba(0, 0, 0, 0.78);
          border-radius: 19rpx;
          z-index: 9999;
        }
        &-video {
          width: 100%;
          height: 100%;
        }
      }
      &-cover {
        position: absolute;
        top: 40%;
        left: 115rpx;
        &-content {
          width: 520rpx;
          height: 734rpx;
          background-color: #545454;
          border-radius: 19rpx;
          overflow: hidden;
          position: relative;
          &-button {
            top: initial;
            position: absolute;
            bottom: 47rpx;
            left: 50%;
            transform: translateX(-50%);
            white-space: nowrap;
          }
        }
        &-info {
          color: #cbcbcb;
          font-size: 24rpx;
          margin-top: 30rpx;
        }
        &-share {
          position: absolute;
          border: 1px dashed #000;
          box-sizing: border-box;
          width: 100%;
          z-index: 1;
          user-select: none;
          touch-action: none; /* 防止浏览器默认的滚动行为 */
        }
      }
    }
    &-fill {
      padding-top: 34rpx;
      &-gather {
        display: flex;
        align-items: center;
        .space {
          margin: 0 26rpx;
          color: #fff;
        }
      }
      &-time {
        width: 100%;
        box-sizing: border-box;
        margin-bottom: 17rpx;
      }
      &-time:last-child {
        margin-bottom: 0;
      }
      .input,
      .textarea {
        background-color: #959595 !important;
        border-radius: 19rpx;
        color: #fff;
        padding: 8.5rpx 17rpx !important;
        width: 100%;
        box-sizing: border-box;
        .input-placeholder {
          color: #cbcbcb !important;
        }
      }
      .textarea {
        min-height: 122.093rpx;
      }
    }
  }
</style>
